﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;
using TyMES.ViewModel.baseinformation.BatchCompilationsVMs;
using TyMES.Model.BaseInformation;
using TyMES.Communication;
using TyMES.Communication.Response;
using TyMES.Services;
using TyMES.Model.Record;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.SignalR;
using TyMES.MidWare;
using Aliyun.OSS;
using TyMES.PassStationCommunication;
using System.Threading.Tasks;
using static TyMES.Communication.Response.UIResponse;


namespace TyMES.Controllers
{
    [Area("baseinformation")]
    [AuthorizeJwtWithCookie]
    [ActionDescription("批次基础信息管理")]
    [ApiController]
    [Route("api/BatchCompilations")]
	public partial class BatchCompilationsController : BaseApiController
    {
        private readonly PassStationService passStationService;
        private readonly IConfiguration configuration;
        private string _LineCode;
        private string factoryCode;
        private readonly IHubContext<NotificationHub> notification;

        public BatchCompilationsController(PassStationService passStationService, IConfiguration configuration, IHubContext<NotificationHub> notificationHub)
        {
            this.passStationService = passStationService;
            this.configuration = configuration;
            this._LineCode = configuration["LineCode"];
            this.factoryCode = configuration["FactoryCode"];
            this.notification = notificationHub;
        }
        [ActionDescription("Sys.Search")]
        [HttpPost("Search")]
		public IActionResult Search(BatchCompilationsSearcher searcher)
        {
            if (ModelState.IsValid)
            {
                var vm = Wtm.CreateVM<BatchCompilationsListVM>(passInit: true);
                vm.Searcher = searcher;
                return Content(vm.GetJson());
            }
            else
            {
                return BadRequest(ModelState.GetErrorJson());
            }
        }

        [ActionDescription("Sys.Get")]
        [HttpGet("{id}")]
        public BatchCompilationsVM Get(string id)
        {
            var vm = Wtm.CreateVM<BatchCompilationsVM>(id);
            return vm;
        }

        [ActionDescription("Sys.Create")]
        [HttpPost("Add")]
        public IActionResult Add(BatchCompilationsVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                var judgerepeat = DC.Set<BatchCompilations>().Where(x => x.stationCode == vm.Entity.stationCode && x.materialCode == vm.Entity.materialCode && x.batchCode == vm.Entity.batchCode).FirstOrDefault();
                if (judgerepeat != null)
                {
                    return BadRequest($"工位{vm.Entity.stationCode}已存在物料编码{vm.Entity.materialCode}，批次码{vm.Entity.batchCode}的批次信息，请勿重复添加");
                }
                vm.DoAdd();
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }

        }

        [ActionDescription("Sys.Edit")]
        [HttpPut("Edit")]
        public IActionResult Edit(BatchCompilationsVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                vm.DoEdit(false);
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }

		[HttpPost("BatchDelete")]
        [ActionDescription("Sys.Delete")]
        public IActionResult BatchDelete(string[] ids)
        {
            var vm = Wtm.CreateVM<BatchCompilationsBatchVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = ids;
            }
            else
            {
                return Ok();
            }
            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(ids.Count());
            }
        }


        [ActionDescription("Sys.Export")]
        [HttpPost("ExportExcel")]
        public IActionResult ExportExcel(BatchCompilationsSearcher searcher)
        {
            var vm = Wtm.CreateVM<BatchCompilationsListVM>();
            vm.Searcher = searcher;
            vm.SearcherMode = ListVMSearchModeEnum.Export;
            return vm.GetExportData();
        }

        [ActionDescription("Sys.CheckExport")]
        [HttpPost("ExportExcelByIds")]
        public IActionResult ExportExcelByIds(string[] ids)
        {
            var vm = Wtm.CreateVM<BatchCompilationsListVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = new List<string>(ids);
                vm.SearcherMode = ListVMSearchModeEnum.CheckExport;
            }
            return vm.GetExportData();
        }

        [ActionDescription("Sys.DownloadTemplate")]
        [HttpGet("GetExcelTemplate")]
        public IActionResult GetExcelTemplate()
        {
            var vm = Wtm.CreateVM<BatchCompilationsImportVM>();
            var qs = new Dictionary<string, string>();
            foreach (var item in Request.Query.Keys)
            {
                qs.Add(item, Request.Query[item]);
            }
            vm.SetParms(qs);
            var data = vm.GenerateTemplate(out string fileName);
            return File(data, "application/vnd.ms-excel", fileName);
        }

        [ActionDescription("Sys.Import")]
        [HttpPost("Import")]
        public ActionResult Import(BatchCompilationsImportVM vm)
        {
            if (vm!=null && (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData()))
            {
                return BadRequest(vm.GetErrorJson());
            }
            else
            {
                return Ok(vm?.EntityList?.Count ?? 0);
            }
        }

        [ActionDescription("获取新批次信息")]
        [HttpPost("GetNewBatch")]
        public async Task<ResponseBase> GetNewBatch(BatchComplitionResponse.BatchUpdateInfo info)
        {
            StationLogRecord stationLog = new StationLogRecord();
            try
            {
                var suplierInfo = await passStationService.GetInfoFromScanData("V:", info);
                if (!suplierInfo.Success)
                {
                    await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                    return suplierInfo;
                }

                var materialinfo = await passStationService.GetInfoFromScanData("M:", info);
                if (!materialinfo.Success)
                {
                    await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                    return materialinfo;
                }
                var batchinfo = await passStationService.GetInfoFromScanData("B:", info);
                if (!batchinfo.Success)
                {
                    await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                    return batchinfo;
                }
                var judgeRepeat = await passStationService.JudgeBatchRepeat(materialinfo.Mesg.Substring(0, materialinfo.Mesg.Length - 4), batchinfo.Mesg, info.stationCode);
                if (!judgeRepeat.Success)
                {
                    //await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                    var repeatBatch = DC.Set<BatchCompilations>().Where(x => x.stationCode == info.stationCode && x.materialCode == materialinfo.Mesg.Substring(0, materialinfo.Mesg.Length - 4) && x.batchCode == batchinfo.Mesg).FirstOrDefault();
                    repeatBatch.isUse = true;
                    repeatBatch.UpdateTime = DateTime.Now;
                    DC.SaveChanges();
                    await passStationService.stationlogadd2(stationLog, info.lineCode, info.stationCode, "", "bad", judgeRepeat.Mesg);
                    return new ResponseBase(false,$"已重新启用批次物料{materialinfo.Mesg.Substring(0, materialinfo.Mesg.Length - 4)}的{batchinfo.Mesg}批次");
                }
                BatchCompilations batch = new BatchCompilations();
                
                batch.lineCode = info.lineCode;
                batch.stationCode = info.stationCode;
                batch.materialCode = materialinfo.Mesg.Substring(0, materialinfo.Mesg.Length - 4);
                batch.materialName = await passStationService.GetMaterialNameByMaterialCode(batch.materialCode);
                batch.batchSingleCostQty = "0";
                batch.batchMarginQty = "0";
                batch.batchAddQty = "0";
                batch.batchCode = batchinfo.Mesg;
                batch.Filed1 = suplierInfo.Mesg;
                batch.isUse = true;
                batch.UpdateTime = DateTime.Now;
                DC.Set<BatchCompilations>().Add(batch);
                DC.SaveChanges();
                await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                return new ResponseBase(true, "");
            }
            catch(Exception ex) 
            {
                await passStationService.stationlogadd(stationLog, info.lineCode, info.stationCode, "", "bad", ex.Message);
                return new ResponseBase(false, ex.Message);
            }
               
        }


        [ActionDescription("手动添加批次")]
        [HttpPost("ManualAddBatch")]
        public async Task<ResponseBase> ManualAddBatch(BatchComplitionResponse.ManualUpdateInfo info)
        {
            StationLogRecord stationLog = new StationLogRecord();
            try
            {
                if (info.materialCode == "" || info.materialCode == null || info.batchCode == "" || info.batchCode == null || info.suplierID == null||info.suplierID =="")
                {
                    return new ResponseBase(false, "物料编码、批次码或供应商代码不能为空");
                }
                string materialName = await passStationService.GetMaterialNameByMaterialCode(info.materialCode);
                if (info.batchAddQty == null || info.batchAddQty == "")
                    info.batchAddQty = "0";
                if (info.batchSingleCostQty == null || info.batchSingleCostQty == "")
                    info.batchSingleCostQty = "0";
                if (info.batchMarginQty == null || info.batchMarginQty == "")
                    info.batchMarginQty = "0";
                var batch_exist = DC.Set<BatchCompilations>().Where(x => x.stationCode == info.stationCode && x.materialCode == info.materialCode && x.batchCode == info.batchCode).FirstOrDefault();
                if (batch_exist!=null)
                {

                    batch_exist.batchAddQty = info.batchAddQty;
                    batch_exist.batchSingleCostQty = info.batchSingleCostQty;
                    batch_exist.batchMarginQty = (Convert.ToInt32(info.batchMarginQty) + Convert.ToInt32(info.batchAddQty)).ToString();
                    batch_exist.isUse = true;
                    batch_exist.materialName = materialName;
                    batch_exist.Filed1 = info.suplierID;
                    batch_exist.UpdateTime = DateTime.Now;
                    DC.SaveChanges();
                    return new ResponseBase(true, "启用物料编码为["+info.materialCode+"]的["+info.batchCode+ "]批次");
                }
               

                BatchCompilations batch = new BatchCompilations();
                batch.Filed1 = info.suplierID;
                batch.lineCode = info.lineCode;
                batch.stationCode = info.stationCode;
                batch.materialCode = info.materialCode;
                batch.materialName = materialName;
                batch.batchCode = info.batchCode;
                batch.batchAddQty = info.batchAddQty;
                batch.batchSingleCostQty = info.batchSingleCostQty;
                batch.UpdateTime = DateTime.Now;
                batch.batchMarginQty = (Convert.ToInt32( info.batchMarginQty)+Convert.ToInt32(info.batchAddQty)).ToString();
                batch.isUse = true;
                DC.Set<BatchCompilations>().Add(batch);
                DC.SaveChanges();
                await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(info.lineCode, info.stationCode));
                return new ResponseBase(true, "");
            }
            catch(Exception ex)
            {
                await passStationService.stationlogadd(stationLog, info.lineCode, info.stationCode, "", "bad", ex.Message);
                return new ResponseBase(false, ex.Message);
            }
        }

        [ActionDescription("手动禁用批次")]
        [HttpPost("ManualForbiddenBatch")]
        public async Task<ResponseBase> ManualForbiddenBatch(BatchComplitionResponse.ManualUpdateInfo info)
        {
            try
            {
                var batch_exist = DC.Set<BatchCompilations>().Where(x => x.stationCode == info.stationCode && x.materialCode == info.materialCode && x.batchCode == info.batchCode).FirstOrDefault();
                if (batch_exist != null)
                {
                    batch_exist.isUse = false;
                    batch_exist.UpdateTime = DateTime.Now;
                    DC.SaveChanges();
                    return new ResponseBase(true, "禁用物料编码为[" + info.materialCode + "]的[" + info.batchCode + "]批次");
                }
                return new ResponseBase(false, "此物料编码下的此批次信息不存在");
            }
            catch (Exception ex)
            {
                return new ResponseBase(false, ex.Message);
            }
        }

        [ActionDescription("添加批次物料黑名单")]
        [HttpPost("AddBlacklist")]
        public async Task<ResponseBase> AddBlacklist(BatchCompilations batchCompilation)
        {
            try
            {
                BatchBlacklist batchBlacklist = new BatchBlacklist();
                batchBlacklist.materialCode = batchCompilation.materialCode;
                batchBlacklist.materialName = batchCompilation.materialName;
                batchBlacklist.supplementCode = batchCompilation.Filed1;
                batchBlacklist.stationCode = batchCompilation.stationCode;
                batchBlacklist.CreateTime = DateTime.Now;
                DC.Set<BatchBlacklist>().Add(batchBlacklist);
                DC.SaveChanges();
                return new ResponseBase(true, $"工位{batchCompilation.stationCode},物料编码{batchCompilation.materialCode},供应商代码{batchCompilation.Filed1}批次料加入黑名单");
            }
            catch (Exception ex)
            {
                return new ResponseBase(false, ex.Message);
            }
        }

        [ActionDescription("获取批次物料黑名单")]
        [HttpPost("SearchBlacklist")]
        public ActionResult  SearchBlacklist(BatchComplitionResponse.BatchUpdateInfo info)
        {
            try
            {
               var Backlist = DC.Set<BatchBlacklist>().ToList();
                return Ok(Backlist);
            }
            catch (Exception ex)
            {
                return BadRequest(new ResponseBase(false, ex.Message));
            }
        }

        [ActionDescription("移除批次物料黑名单")]
        [HttpPost("RemoveFormBlacklist")]
        public ActionResult RemoveFormBlacklist(BatchBlacklist batchBlacklist)
        {
            try
            {
                var removeBacklist = DC.Set<BatchBlacklist>().Where(x=>x.stationCode==batchBlacklist.stationCode&&x.materialCode==batchBlacklist.materialCode&&x.supplementCode==batchBlacklist.supplementCode);
                DC.Set<BatchBlacklist>().RemoveRange(removeBacklist);
                DC.SaveChanges();
                return Ok(new ResponseBase(true, $"从黑名单中移除工位{batchBlacklist.stationCode},物料编码{batchBlacklist.materialCode},供应商代码{batchBlacklist.supplementCode}批次料"));
            }
            catch (Exception ex)
            {
                return BadRequest(new ResponseBase(false, ex.Message));
            }
        }
    }
}
